home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / ABox 1.9.5 / CPlus Files / ABObject.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-26  |  14.3 KB  |  622 lines  |  [TEXT/MMCC]

  1. /*    
  2.     Copyright © 1991-1995 by TopSoft Inc.  All rights reserved.
  3.  
  4.     You may distribute this file under the terms of the TopSoft
  5.     Artistic License, accompanying this package.
  6.     
  7.     This file was developed by George (ty) Tempel in connection with TopSoft, Inc..
  8.     See the Modification History for more details.
  9.  
  10. Product
  11.     About Box
  12.  
  13. FILE
  14.     ABObject.c
  15.  
  16. NAME
  17.     ABObject.c, part of the ABox project source code,
  18.     responsible for handling the AboutBox drawn object stuff.
  19.  
  20. DESCRIPTION
  21.     This file contains defines for the about box modules.
  22.     
  23. DEVELOPED BY
  24.     George (ty) Tempel                ttempel@monmouth.com
  25.     All code in this file, and its associated header file was
  26.     Created by George (ty) Tempel in connection with the TopSoft, Inc.
  27.     "FilterTop" application development, except where noted.
  28.  
  29. CARETAKER - George (ty) Tempel <ttempel@monmouth.com>
  30.      Please consult this person for any changes or suggestions to this file.
  31.  
  32. MODIFICATION HISTORY
  33.  
  34.     dd mmm yy    -    xxx    -    patchxx: description of patch
  35.     9 June 94    -    ty    -    Initial Version Created
  36.     20-july-94    -    ty    -    initial version released
  37.     12-aug-94    -    ty    -    1.0.8 -- added mix-in class ABUEnvQD
  38.                             for handling of quickdraw features
  39.     12-jan-95    -    ty    -    1.0.10 -- changed how the frames are drawn, inspired
  40.                             by the adorners of macapp--the frame will draw around
  41.                             the rect specified, not inside the rect. Thus,
  42.                             there will be no difference when viewing in 1bit vs n-bit
  43.     10-mar-95    -    ty    -    1.2 removed utility methods from here to ABUEnvQD
  44.                                 since they were quickdraw related; inclusion of some
  45.                                 new methods for handling DeviceLoop driven 3d frames
  46.                                 of the object (pretty neat stuff!)
  47.     20-mar-95    -    ty    -    1.4 fixes to properly restore the clip region
  48.     21-mar-95    -    ty    -    1.5    fixes for ColorQD cautions on non-colorQD machines and
  49.                                 better region handling for multiple devices
  50.     23-may-95    -    ty    -    changes for compatibility with the CodeWarrior CW6
  51.                             release and the associated Universal Headers from Apple:
  52.                             most methods that returned references now have "Ref" at
  53.                             the end of their methods names to prevent possible collisions
  54.                             with datatypes and classes of the same name (older versions
  55.                             of the compiler didn't have a problem with this).
  56.     25-oct-95    -    ty    -    changes for "const" usage under CW7; simplification of Boolean
  57.                             query methods
  58.  
  59. */
  60.  
  61. /*===========================================================================*/
  62.  
  63. /*======= Segmentation directives ========*/
  64.  
  65. #ifdef USE_MANUAL_SEGMENTATION
  66. #pragma segment ty
  67. #endif
  68.  
  69. /*============ Header files ==============*/
  70.     
  71. #include     "ABObject.h"
  72.  
  73. /*=============== Globals ================*/
  74.  
  75. /*================ CODE ==================*/
  76.  
  77. #ifndef topLeft
  78. #define topLeft(r) (((Point *)&(r))[0])
  79. #endif
  80.  
  81. #ifndef botRight
  82. #define botRight(r) (((Point *)&(r))[1])
  83. #endif
  84.  
  85.  
  86. /*=============================== ABObject::ABObject ================================*/
  87. ABObject::ABObject(void)
  88. {
  89.     mRefCon = 0;
  90.     mVisibleObject = false;
  91.     
  92.     mOurWindow = NULL;
  93.     
  94.     mObjectRect.top = mObjectRect.bottom = mObjectRect.right = mObjectRect.left = 0;
  95.     
  96. } // end ABObject
  97.  
  98.  
  99.  
  100. /*=============================== ABObject::~ABObject ================================*/
  101. ABObject::~ABObject(void)
  102. {
  103. } // end ~ABObject
  104.  
  105.  
  106.  
  107. /*=============================== ABObject::Draw ================================*/
  108. OSErr    ABObject::Draw(WindowPtr window)
  109. {
  110.     this->OurWindowRef() = window;
  111.  
  112.     //    begin here...
  113.     //
  114.     //    OVERRIDE THIS FUNCTION
  115.     return this->DrawFrame();
  116. } // end Draw
  117.  
  118.  
  119.  
  120. /*=============================== ABObject::Update ================================*/
  121. OSErr    ABObject::Update(WindowPtr window)
  122. {
  123.     
  124.     //    begin here...
  125.     //
  126.     //    OVERRIDE THIS FUNCTION
  127.     
  128.     return this->Draw(window);
  129.     
  130. } // end Update
  131.  
  132.  
  133.  
  134.  
  135. /*=============================== ABObject::Event ================================*/
  136. Boolean    ABObject::Event(EventRecord* /*eventRec*/)
  137. {
  138. //#pragma unused (eventRec)
  139.     
  140.     //    begin here...
  141.     //
  142.     //    OVERRIDE THIS FUNCTION
  143.     
  144.     return false;
  145.     
  146. } // end Event
  147.  
  148.  
  149.  
  150. /*=============================== ABObject::Stop ================================*/
  151. OSErr    ABObject::Stop(void)
  152. {
  153.     
  154.     //    begin here...
  155.     //
  156.     //    OVERRIDE THIS FUNCTION
  157.     
  158.     return noErr;
  159. } // end Stop
  160.  
  161.  
  162.  
  163.  
  164. /*=============================== ABObject::CheckFile ================================*/
  165. Boolean    ABObject::CheckFile(FSSpecPtr /*fssptr*/)
  166. {
  167. //#pragma    unused (fssptr)
  168.  
  169.     //    begin here...
  170.     //
  171.     //    OVERRIDE THIS FUNCTION
  172.     
  173.     return false;
  174. } // end CheckFile
  175.  
  176.  
  177.  
  178. /*=============================== ABObject::InitializeObject ================================*/
  179. OSErr    ABObject::InitializeObject(void)
  180. {
  181.     //    begin here...
  182.     //
  183.     //    OVERRIDE THIS FUNCTION
  184.     
  185.     return noErr;
  186. } // end InitializeObject
  187.  
  188.  
  189.  
  190. /*=============================== ABObject::Resize ================================*/
  191. OSErr    ABObject::Resize(Rect const* /*field*/)
  192. {
  193. //#pragma    unused (field)
  194.     
  195.     //    begin here...
  196.     //
  197.     //    OVERRIDE THIS FUNCTION
  198.     
  199.     return noErr;
  200. } // end Resize
  201.  
  202.  
  203.  
  204.  
  205.  
  206.  
  207. /*=============================== ABObject::GetProperty ================================*/
  208. OSErr    ABObject::GetProperty(ABProperty prop, 
  209.                                 void *ptr, 
  210.                                 long *ptrSize)
  211. {
  212.     OSErr    error = noErr;
  213.     long    pSize;
  214.     
  215.     //    begin here...
  216.     
  217.     if (!ptr)
  218.         return kABPropertyNullStorage;
  219.     
  220.     switch (prop)
  221.     {
  222.         case    kABObjectRefCon:
  223.                     *((long *)ptr) = mRefCon;
  224.                     pSize = kABObjectRefConSize;
  225.                     break;
  226.         case    kABObjectVisible:
  227.                     *((Boolean *)ptr) = this->VisibleObject();
  228.                     pSize = kABObjectVisibleSize;
  229.                     break;
  230.         case    kABObjectRect:
  231.                     (*(Rect *)ptr) = this->ObjectRect();
  232.                     pSize = kABObjectRectSize;
  233.                     break;
  234.         default:
  235.                     error = kABObjectSuperProperty::GetProperty (prop, ptr, ptrSize);
  236.                     break;
  237.     } // end switch block
  238.     
  239.     if (ptrSize && !error)
  240.         *ptrSize = pSize;
  241.     return error;
  242.     
  243. } // end GetProperty
  244.  
  245.  
  246.  
  247. /*=============================== ABObject::SetProperty ================================*/
  248. OSErr    ABObject::SetProperty(ABProperty prop, 
  249.                                 void *ptr, 
  250.                                 long ptrSize)
  251. {
  252.     OSErr    error = noErr;
  253.     
  254.     //    begin here...
  255.     
  256.     if (!ptr)
  257.         return kABPropertyNullStorage;
  258.     
  259.     switch (prop)
  260.     {
  261.         case    kABObjectRefCon:
  262.                     mRefCon = *((long *)ptr);
  263.                     break;
  264.         case    kABObjectVisible:
  265.                     this->VisibleObject() = *((Boolean *)ptr);
  266.                     break;
  267.         case    kABObjectRect:
  268.                     this->ObjectRect() = (*(Rect *)ptr);
  269.                     break;
  270.         default:
  271.                     error = kABObjectSuperProperty::SetProperty (prop, ptr, ptrSize);
  272.                     break;
  273.     } // end switch block
  274.     
  275.     return error;
  276.     
  277. } // end SetProperty
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284. /*=============================== ABObject::ScaleRectToFit ================================*/
  285. //
  286. //    ScaleRectToFit will scale a rectangle to fit wholly within another, with an
  287. //    optional reduction factor (expressed as 0.75 for a reduction to 75%, or 1.0
  288. //    for normal).
  289. //
  290. //    The function returns a pointer to the newly scaled rectangle in the parameter list,
  291. //    and returns an OSErr for error processing.
  292. //
  293. //OSErr    ABObject::ScaleRectToFit(Rect& item, Rect const *area, float factor)
  294. OSErr    ABObject::ScaleRectToFit(Rect& item, const Rect& area, float factor)
  295. {
  296.     OSErr    error = noErr;
  297.  
  298.     float    scale,
  299.             xratio,
  300.             yratio,
  301.             extra = factor;
  302.     
  303.     short    rectWidth,
  304.             rectHeight,
  305.             areaWidth,
  306.             areaHeight;
  307.     
  308.     
  309.     //    begin...
  310.     
  311.     //    begin here...
  312.     //
  313.     rectWidth = item.right - item.left;
  314.     rectHeight = item.bottom - item.top;
  315.     
  316.     areaWidth = area.right - area.left;
  317.     areaHeight = area.bottom - area.top;
  318.  
  319.     if ((rectWidth <= areaWidth) && (rectHeight <= areaHeight)) 
  320.     {
  321.         //    the rect fits already...
  322.         //
  323.     } else {
  324.         xratio = (float)(areaWidth * extra) / (float)rectWidth;
  325.         yratio = (float)(areaHeight * extra) / (float)rectHeight;
  326.         
  327.         scale = (xratio < yratio) ? xratio : yratio;
  328.         
  329.         item.right = item.left + rectWidth * scale;
  330.         item.bottom = item.top + rectHeight * scale;
  331.         
  332.     }    //    end if else block...    
  333.     
  334.     return error;
  335.     
  336. }    //    end of function ScaleRectToFit()
  337.  
  338.  
  339.  
  340. /*=============================== ABObject::CanDraw3dBezel ==================================*/
  341. //
  342. //    returns true if the pixel depth is sufficient for the bezel effect
  343. //
  344. Boolean
  345. ABObject::CanDraw3dBezel(short inDepth)
  346. {
  347.     return inDepth >= kABminPixelDepthForBezel;
  348. }
  349.  
  350.  
  351.  
  352.  
  353.  
  354. /*=============================== ABObject::EraseFrame ===============================*/
  355. //
  356. //    this function will erase the beveled frame from around a rect area
  357. //
  358. //    it will return an OSErr type to indicate error conditions.
  359. //
  360. //
  361. //    is called by:
  362. //
  363. OSErr
  364. ABObject::EraseFrame (void) const
  365. {
  366.     return this->EraseFrame(this->ObjectRect());
  367. }    //    end of function EraseFrame()
  368.  
  369.  
  370.  
  371.  
  372.  
  373. /*=============================== ABObject::EraseFrame ===============================*/
  374. //
  375. //    this function will erase the beveled frame from around a rect area
  376. //
  377. //    it will return an OSErr type to indicate error conditions.
  378. //
  379. //
  380. //    is called by:
  381. //
  382. OSErr    
  383. ABObject::EraseFrame (const Rect& rect)
  384. {
  385.     OSErr    error = noErr;
  386.     
  387.     //    begin here...
  388.     
  389.     Rect theRect = rect;
  390.     
  391.     if (::EmptyRect(&theRect))
  392.         return noErr;
  393.     
  394.     ::InsetRect (&theRect, -kABbezelWidth, -kABbezelWidth);
  395.     theRect.right += 1;
  396.     theRect.bottom += 1;
  397.     ::EraseRect (&theRect);
  398.     theRect.right -= 1;
  399.     theRect.bottom -= 1;
  400.     ::InsetRect (&theRect, kABbezelWidth, kABbezelWidth);
  401.  
  402.     return (error);
  403.     
  404. }    //    end of function EraseFrame()
  405.  
  406.  
  407.  
  408.  
  409.  
  410. /*=============================== ABObject::DrawFrame ===============================*/
  411. //
  412. //    this function will draw a beveled frame around a rect area
  413. //
  414. OSErr
  415. ABObject::DrawFrame (void) const
  416. {
  417.     return this->DrawFrame(this->ObjectRect());
  418. }
  419.  
  420.  
  421.  
  422. /*=============================== ABObject::DrawFrame ===============================*/
  423. //
  424. //    this function will draw a beveled frame around a rect area
  425. //
  426. //    The function returns an OSErr to indicate error conditions.
  427. //
  428. OSErr    
  429. ABObject::DrawFrame (const Rect& inRect)
  430. {
  431.     OSErr anError = noErr;
  432.     
  433.     //    draw the frame via device loop calls...better in the long run if we can do this!
  434.     
  435.     RgnHandle theDrawRegion = ::NewRgn();
  436.     DeviceLoopDrawingUPP theDrawUPP = NewDeviceLoopDrawingProc(ABObject::DeviceLoopDrawFrame);
  437.     Rect theRect = inRect;
  438.     
  439.     if (theDrawUPP && theDrawRegion)
  440.     {
  441.         //    construct a region from the given rect...
  442.         ::RectRgn (theDrawRegion, &theRect);
  443.         
  444.         //    now invoke the toolbox DeviceLoop
  445.         ::DeviceLoop (theDrawRegion, 
  446.                         theDrawUPP, 
  447.                         (long)&theRect, 
  448.                         allDevices);
  449.     } else {
  450.         //    there was a problem, so try and draw the region best we can...
  451.         ABUEnvQD hasColorQD;
  452.         ABObject::DeviceLoopDrawFrame ((hasColorQD.HasColorQD() ? ABUEnvQD::GetPixelDepth(::GetGDevice()) : 1),
  453.                                         allDevices,
  454.                                         NULL,
  455.                                         (long)&theRect);
  456.         
  457.     }
  458.     
  459.     if (theDrawRegion)
  460.     {
  461.         ::DisposeRgn(theDrawRegion);
  462.         theDrawRegion = NULL;
  463.     }
  464.     
  465.     if (theDrawUPP)
  466.     {
  467.         DisposeRoutineDescriptor(theDrawUPP);
  468.         theDrawUPP = NULL;
  469.     }
  470.         
  471.     return anError;
  472.     
  473. }
  474.  
  475.  
  476. /*=============================== ABObject::DeviceLoopDrawFrame ===============================*/
  477. //
  478. //    this function will draw a beveled frame around a rect area
  479. //    following the suggestions put forth in Develop #15 for 3d effects 
  480. //    in user interfaces.
  481. //
  482. //    It is _this_ method that does the actual frame drawing...all other DrawFrame
  483. //    method eventually lead here via DeviceLoop...
  484. //
  485. pascal void    
  486. ABObject::DeviceLoopDrawFrame (short inDepth, short inDeviceFlags, GDHandle inDevice, long inUserData)
  487. {
  488. #pragma unused(inDeviceFlags)
  489.  
  490.     OSErr            error = noErr;
  491.     
  492.     Rect userAreaToDraw = *((Rect*)inUserData);
  493.     RGBColor    frameColor, prevColor;
  494.     
  495.     //    begin here...
  496.     
  497.     if (::EmptyRect(&userAreaToDraw))
  498.         return;
  499.     
  500.     //    1.1--expand the rect area so we can draw stuff
  501.     ::InsetRect (&userAreaToDraw, -kABbezelWidth, -kABbezelWidth);
  502.     Rect drawableIntersection = userAreaToDraw;
  503.  
  504.     //    now determine if we should even bother drawing here just as yet...
  505.     RgnHandle theClipRegion = ::NewRgn();
  506.     if (theClipRegion)
  507.         ::GetClip(theClipRegion);
  508.         
  509.     RgnHandle theDrawRegion = ::NewRgn();
  510.     
  511.     ABUEnvQD hasColorQD;
  512.     
  513.     Rect deviceBounds;
  514.     Rect globalAreaToDraw = drawableIntersection;
  515.  
  516.     ::SetRect(&deviceBounds, 0, 0, 0, 0);
  517.     if (inDevice)
  518.     {
  519.         deviceBounds = (*inDevice)->gdRect;
  520.     } else {
  521.         if (hasColorQD.HasColorQD())
  522.         {
  523.             GDHandle device = ::GetGDevice();
  524.             if (device)
  525.                 deviceBounds = (*device)->gdRect;
  526.         }
  527.     }
  528.         
  529.     ::LocalToGlobal(&topLeft(globalAreaToDraw));
  530.     ::LocalToGlobal(&botRight(globalAreaToDraw));
  531.     
  532.     if (::SectRect(&deviceBounds, &globalAreaToDraw, &drawableIntersection))
  533.     {
  534.         //    there is an intersection, so set things up...
  535.         if (theDrawRegion && theClipRegion)
  536.         {
  537.             //    convert back to local coords...
  538.             ::GlobalToLocal(&topLeft(drawableIntersection));
  539.             ::GlobalToLocal(&botRight(drawableIntersection));
  540.             
  541.             //    start setting up the drawing regions and clip regions now...
  542.             ::RectRgn (theDrawRegion, &drawableIntersection);
  543.             
  544.             //    set theDrawRegion to be the clipped area, just to
  545.             //    be nice
  546.  
  547.             if (::EmptyRgn(theClipRegion) == false)
  548.                 ::SectRgn(theDrawRegion, theClipRegion, theDrawRegion);
  549.             
  550.             //    now clip to the visRgn too...
  551.             ::SectRgn(theDrawRegion, qd.thePort->visRgn, theDrawRegion);
  552.             
  553.             //    now set the _new_ clip region...
  554.             ::SetClip (theDrawRegion);
  555.         }
  556.     }
  557.     
  558.     //    see if there really was an intersection to draw into...
  559.     if (theDrawRegion && theClipRegion && (::EmptyRgn(theDrawRegion) == false))
  560.     {
  561.         //    we should always get here, but just to make certain...
  562.         
  563.         if (ABObject::CanDraw3dBezel(inDepth) && inDevice && hasColorQD.HasColorQD())
  564.         {
  565.             //    when called on a system without ColorQuickdraw, the inDevice parameter is
  566.             //    set to NULL...
  567.     
  568.             //    now do the draw...
  569.             ::GetForeColor (&prevColor);
  570.             
  571.             //    draw the left & top first...
  572.             //    set the color
  573.     
  574.             frameColor.blue = frameColor.red = frameColor.green = k3D_lineMedLightGrey;
  575.             if (hasColorQD.HasColorQD())
  576.                 ::RGBForeColor (&frameColor);    
  577.             
  578.             ::MoveTo (userAreaToDraw.left, userAreaToDraw.bottom);
  579.             ::LineTo (userAreaToDraw.left, userAreaToDraw.top);
  580.             ::LineTo (userAreaToDraw.right, userAreaToDraw.top);
  581.  
  582.             //    draw the bottom and right...
  583.             //    set the bottom/right colors        
  584.             frameColor.blue = frameColor.red = frameColor.green = k3D_lineWhite;
  585.             if (hasColorQD.HasColorQD())
  586.                 ::RGBForeColor (&frameColor);    
  587.             
  588.             ::InsetRgn (theDrawRegion, -kABbezelWidth, -kABbezelWidth);
  589.             ::SetClip (theDrawRegion);
  590.             ::MoveTo (userAreaToDraw.left, userAreaToDraw.bottom);
  591.             ::LineTo (userAreaToDraw.right, userAreaToDraw.bottom);
  592.             ::LineTo (userAreaToDraw.right, userAreaToDraw.top);
  593.         
  594.             if (hasColorQD.HasColorQD())
  595.                 ::RGBForeColor(&prevColor);
  596.         
  597.         } else {
  598.             ::FrameRect (&userAreaToDraw);
  599.         
  600.         }    //    end if else block...
  601.     
  602.     }
  603.     
  604.     if (theClipRegion)
  605.     {
  606.         //    restore the clip region
  607.         ::SetClip (theClipRegion);
  608.         ::DisposeRgn(theClipRegion);
  609.         theClipRegion = NULL;
  610.     }
  611.     
  612.     if (theDrawRegion)
  613.     {
  614.         ::DisposeRgn(theDrawRegion);
  615.         theDrawRegion = NULL;
  616.     }
  617.     
  618.     return;
  619.     
  620. }    // end of function DrawFrame()
  621.  
  622.